package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.util.ApplicationContextHelper;
import com.bifang.module.base.core.helper.ApiModel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.vo.eduStudentEnrollBefore.BatchCreateVO;
import com.jwsoft.manager.common.vo.eduStudentEnrollCalculate.EduStudentEnrollCalculateKeyVO;
import com.jwsoft.manager.common.vo.eduStudentEnrollCalculate.EduStudentEnrollCalculateQueryVO;
import com.jwsoft.manager.common.vo.eduStudentEnrollCalculate.EduStudentEnrollCalculateVO;
import com.jwsoft.manager.core.dao.model.EduStudentEnrollCalculate;
import com.jwsoft.manager.core.dao.service.EduStudentEnrollCalculateService;
import com.jwsoft.manager.core.integration.EduStudentEnrollCalculateIntegration;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
/**
 * 报名预测管理业务实现类
 *
 * @author zhiyuan
 * @since 2023-03-06
 */
@ApiService(funcCode = "enrollCalculate", title = "报名预测管理")
public class EduStudentEnrollCalculateIntegrationImpl implements EduStudentEnrollCalculateIntegration {

    @Autowired
    public EduStudentEnrollCalculateService eduStudentEnrollCalculateService;
    private final String createBatchBeforeCatch = "task:createBatchBeforeCatch";
    @Autowired
    private RedisHelper redisHelper;
    @Autowired
    EduHelper eduHelper;
    @Override
    @OpApi(funcCode = "enrollCalculate0001", title = "报名预测管理分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduStudentEnrollCalculateVO> getList(EduStudentEnrollCalculateQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        List<EduStudentEnrollCalculate> list = eduStudentEnrollCalculateService.list();
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduStudentEnrollCalculate> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduStudentEnrollCalculateVO> resultList = Convert.toList(EduStudentEnrollCalculateVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(DemoDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "enrollCalculate0002", title = "报名预测管理根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduStudentEnrollCalculateVO getById(EduStudentEnrollCalculateKeyVO vo) {
        EduStudentEnrollCalculate entity = eduStudentEnrollCalculateService.getById(vo.getEnrollBeforeId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduStudentEnrollCalculateVO result = Convert.convert(EduStudentEnrollCalculateVO.class, entity);
        return result;
    }
    /** 保存前统一校验*/
    @Override
    @OpApi(funcCode = "enrollCalculate0003", title = "报名预测管理保存前校验", funcType = FuncTypeEnum.other ,checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduStudentEnrollCalculateVO vo) {
        //主键为空为新增校验

        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "enrollCalculate0004", title = "报名预测管理新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "enrollCalculate0004",
            operationName = "报名预测管理新增",
            dataType = "enrollBeforeId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduStudentEnrollCalculateVO add(EduStudentEnrollCalculateVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduStudentEnrollCalculate entity = Convert.convert(EduStudentEnrollCalculate.class, vo);
        eduStudentEnrollCalculateService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setEnrollBeforeId(entity.getEnrollBeforeId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "enrollCalculate0005", title = "报名预测管理修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "enrollCalculate0005",
            operationName = "报名预测管理修改",
            dataType = "enrollBeforeId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduStudentEnrollCalculateVO edit(EduStudentEnrollCalculateVO vo) {
        if (ObjectUtils.isEmpty(vo.getEnrollBeforeId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduStudentEnrollCalculate oldEntity = eduStudentEnrollCalculateService.getById(vo.getEnrollBeforeId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduStudentEnrollCalculate entity = Convert.convert(EduStudentEnrollCalculate.class, vo);
        eduStudentEnrollCalculateService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "enrollCalculate0006", title = "报名预测管理根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "enrollCalculate0006",
            operationName = "报名预测管理删除",
            dataType = "enrollBeforeId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduStudentEnrollCalculateKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getEnrollBeforeId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduStudentEnrollCalculate entity = eduStudentEnrollCalculateService.getById(vo.getEnrollBeforeId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduStudentEnrollCalculateService.removeById(vo.getEnrollBeforeId());
    }

    @Override
    @OpApi(funcCode = "enrollCalculate0007", title = "报名预测管理批量数据生成", funcType = FuncTypeEnum.edit)
    @Async("commonTaskExecutor")
    public void createCalculateBatch(BatchCreateVO vo) {
        if (redisHelper.hasKey(createBatchBeforeCatch)) {
            throw new AppException("正在批量生成预报名或预测数据中...");
        }
        redisHelper.set(createBatchBeforeCatch, "1", 3600);
        String areaCode=vo.getAreaCode();
        if(StringUtils.isBlank(areaCode)){
            areaCode=eduHelper.thisAreaCode();
        }
        ApiModel apiModel=eduHelper.getEduFunc("createCalculateBatch",areaCode);
        try {
            Object bean = ApplicationContextHelper.getBean(apiModel.getBeanName());
            if (null != bean) {
                apiModel.getMethod().invoke(bean, vo);
            }else {
                throw new AppException("未查询到方法");
            }
        }catch (AppException e ){
            throw e;
        }catch (InvocationTargetException e ){
            try{
                AppException exception= (AppException) e.getTargetException();
                throw new AppException(exception.getMsg(),e.getTargetException());
            }catch (Exception ex){
                throw new AppException(e.getCause().getMessage(),e.getTargetException());
            }

        }catch (Exception e ){
            throw new AppException( e.getMessage(),e);
        }finally {
            redisHelper.del(createBatchBeforeCatch);
        }
    }
}
